// 作者:于大明

//------------------------------mock数据引入---------------------------
import privateChatMock from './privateChat_mock.js';

//------------------------------mixins引入---------------------------
import privateChatMixins from './privateChat_mixins.js';


//------------------------------组件引入-------------------------------
import goEasyAudioPlayer from '@/pages/30message/50go-easy-audio-player/go-easy-audio-player.vue';
import customMessage from '@/pages/30message/60custom-message/custom-message.vue';
import emojiDecoder from '@/pages/30message/emojiDecoder';
const recorderManager = uni.getRecorderManager();

//-------------------------Service引入----------------------------------
import CY17 from '@/service/CY/CY17AppService.js';

//--------------------------核心规范-------------------------------------
//1 能不能在页面单行代码实现
//2 能不能不用data methods去实现这个功能(有返回值不用传参数的用compute,有返回值有传参的那么使用filters实现)
//3 以最少的代码实现功能(需要封装除外)
//4 相同代码一定更要封装 区分职责关系 
//5 新增功能时尽量不改之前的文件 以新增组件进行处理


export default {
    // 组件放在data前面
    components: {
        goEasyAudioPlayer,
		customMessage
    },
    mixins: [privateChatMixins],
    data() {
    	const emojiUrl = 'https://imgcache.qq.com/open/qcloud/tim/assets/emoji/';
    	const emojiMap = {
    		'[么么哒]': 'emoji_3@2x.png',
    		'[乒乓]': 'emoji_4@2x.png',
    		'[便便]': 'emoji_5@2x.png',
    		'[信封]': 'emoji_6@2x.png',
    		'[偷笑]': 'emoji_7@2x.png',
    		'[傲慢]': 'emoji_8@2x.png'
    	};
    	return {
    		//聊天文本框
    		content: '',
    		friend: null,
    		currentUser: null,
    		//消息记录
    		messages: [],
    		//是否加载完所有历史消息
    		allHistoryLoaded: false,
    
    		//定义表情列表
    		emoji : {
    			url : emojiUrl,
    			map : emojiMap,
    			visible: false,
    			decoder:  new emojiDecoder(emojiUrl, emojiMap),
    		},
    		//是否展示‘其他消息类型面板’
    		otherTypesMessagePanelVisible: false,
    		audio : {
    			startTime: null,
    			//语音录音中
    			recording : false,
    			//录音按钮展示
    			visible : false
    		},
    
    		videoPlayer : {
    			visible : false,
    			url : '',
    			context : null
    		},
    		// 展示自定义消息框
    		customMessageFormVisible: false,
    
    		// 展示消息删除弹出框
    		actionPopup:{
    			visible: false,
    			message: null,
                recallable: false,
    		},
    		// 消息选择
    		messageSelector: {
    			visible: false,
    			messages: []
    		}
    	}
    },
    onReady () {
    	this.videoPlayer.context = uni.createVideoContext('videoPlayer',this);
    	// https://uniapp.dcloud.io/api/ui/navigationbar?id=setnavigationbartitle
    	uni.setNavigationBarTitle({
    		title : this.friend.name
    	});
    },
    onShow () {
    	this.otherTypesMessagePanelVisible = false;
    	this.emoji.visible = false;
    },
    onLoad(options) {
    	//聊天对象
    	let friendId = options.to;
    	this.currentUser = uni.getStorageSync('currentUser');
    	//从服务器获取最新的好友信息
    	this.friend = this.$myIm.findUserById(friendId);
    
    	this.initialGoEasyListeners();
    	this.loadHistoryMessage(true);
    	// 录音监听器
    	this.initRecorderListeners();
    
    },
    onPullDownRefresh(e) {
    	this.loadHistoryMessage(false);
    },
    onUnload() {
    	//退出聊天页面之前，清空监听器
    	this.goEasy.im.on(this.GoEasy.IM_EVENT.PRIVATE_MESSAGE_RECEIVED, ()=>{});
    	this.goEasy.im.on(this.GoEasy.IM_EVENT.MESSAGE_DELETED, ()=>{});
    },
    methods: {
    	//渲染文本消息，如果包含表情，替换为图片
    	//todo:本不需要该方法，可以在标签里完成，但小程序有兼容性问题，被迫这样实现
    	renderTextMessage(message) {
    		return '<span class="text-content">' + this.emoji.decoder.decode(message.payload.text) + '</span>'
    	},
    	//像微信那样显示时间，如果有几分钟没发消息了，才显示时间
    	//todo:本不需要该方法，可以在标签里完成，但小程序有兼容性问题，被迫这样实现
    	renderMessageDate(message, index) {
    		if (index === 0) {
    			return this.formatDate(message.timestamp)
    		} else {
    			if (message.timestamp - this.messages[index - 1].timestamp > 5 * 60 * 1000) {
    				return this.formatDate(message.timestamp)
    			}
    		}
    		return '';
    	},
    	initialGoEasyListeners() {
    		// 监听私聊消息
    		this.goEasy.im.on(this.GoEasy.IM_EVENT.PRIVATE_MESSAGE_RECEIVED, (message) => {
    			console.log('PRIVATE_MESSAGE_RECEIVED:', message);
    			let senderId = message.senderId;
    			let receiverId = message.receiverId;
    			let friendId = this.currentUser.uuid === senderId?receiverId:senderId;
    			if (friendId === this.friend.uuid) {
    				this.messages.push(message);
    				//聊天时，收到消息标记为已读
    				this.markPrivateMessageAsRead();
    				//收到新消息，是滚动到最底部
    				this.scrollToBottom();
    			}
    		});
    		//监听消息删除
    		this.goEasy.im.on(this.GoEasy.IM_EVENT.MESSAGE_DELETED,(deletedMessages) => {
    			deletedMessages.forEach(message => {
    				let senderId = message.senderId;
    				let receiverId = message.receiverId;
    				let friendId = this.currentUser.uuid === senderId?receiverId:senderId;
    				if (friendId === this.friend.uuid) {
    					let index = this.messages.indexOf(message);
    					if (index > -1) {
    						this.messages.splice(index, 1);
    					}
    				}
    			});
    		});
    	},
    	initRecorderListeners(){
    		// 监听录音开始
    		recorderManager.onStart(() => {
    			this.audio.recording = true;
    			this.audio.startTime = Date.now();
    		});
    		//录音结束后，发送
    		recorderManager.onStop((res) => {
    			let endTime = Date.now();
    			this.audio.recording = false;
    			let duration = endTime - this.audio.startTime;
    			if (duration < 1000) {
    				uni.showToast({
    					icon: 'error',
    					title: '录音时间太短',
    					duration: 500
    				});
    				return;
    			}
    			res.duration = duration;
    			let audioMessage = this.goEasy.im.createAudioMessage({
    				to : {
    					id : this.friend.uuid,
    					type : this.GoEasy.IM_SCENE.PRIVATE,
    					data : {
    						name:this.friend.name,
    						avatar:this.friend.avatar
    					}
    				},
    				file: res,
    				onProgress :function (progress) {
    					console.log(progress)
    				},
    				notification : {
    					title : this.currentUser.name + '发来一段语音',
    					body : '[语音消息]'		// 字段最长 50 字符
    				}
    			});
    			this.sendMessage(audioMessage);
    		});
    		// 监听录音报错
    		recorderManager.onError((res) =>{
    			this.audio.recording = false;
    			recorderManager.stop();
    			uni.showToast({
    				icon: 'none',
    				title: '录音失败,请检查麦克风权限',
    				duration: 1000
    			});
    		})
    	},
    	sendMessage(message){
    		this.messages.push(message);
    		this.scrollToBottom();
    		this.goEasy.im.sendMessage({
    			message: message,
    			onSuccess: function (message) {
    				console.log('发送成功.', message);
    			},
    			onFailed: function (error) {
    				if(error.code === 507){
    					console.log('发送语音/图片/视频/文件失败，没有配置OSS存储，详情参考：https://www.goeasy.io/cn/docs/goeasy-2.x/im/message/media/send-media-message.html');
    				}else{
    					console.log('发送失败:',error);
    				}
    			}
    		});
    	},
    	createTextMessage() {
    		if (this.content.trim() !== '') {
    			let body = this.content;
    			if(this.content.length >= 50){
    				body = this.content.substring(0,30)+'...';
    			}
    			let textMessage = this.goEasy.im.createTextMessage({
    				text: this.content,
    				to : {
    					id : this.friend.uuid,
    					type : this.GoEasy.IM_SCENE.PRIVATE,
    					data : {
    						name:this.friend.name,
    						avatar:this.friend.avatar
    					}
    				},
    				notification : {
    					title : this.currentUser.name + '发来一段文字',
    					body : body
    				}
    			});
    			this.sendMessage(textMessage);
    		}
    		this.content = '';
    	},
    	showActionPopup(message) {
    		const MAX_RECALLABLE_TIME = 3 * 60 * 1000; //3分钟以内的消息才可以撤回
    		this.messageSelector.messages = [message];
    		if ((Date.now() - message.timestamp) < MAX_RECALLABLE_TIME && message.senderId === this.currentUser.uuid && message.status === 'success') {
    			this.actionPopup.recallable = true;
    		} else {
    			this.actionPopup.recallable = false;
    		}
    		this.actionPopup.visible = true;
    	},
    	deleteSingleMessage(){
    		uni.showModal({
    			content: '确认删除？',
    			success: (res) => {
    				this.actionPopup.visible = false;
    				if (res.confirm) {
    					this.deleteMessage();
    				}
    			},
    		})
    	},
    	deleteMultipleMessages(){
    		if (this.messageSelector.messages.length > 0) {
    			uni.showModal({
    				content: '确认删除？',
    				success: (res) => {
    					this.messageSelector.visible = false;
    					if (res.confirm) {
    						this.deleteMessage();
    					}
    				},
    			})
    		}
    	},
    	deleteMessage() {
    		this.goEasy.im.deleteMessage({
    			messages: this.messageSelector.messages,
    			onSuccess: (result)=>{
    				this.messageSelector.messages.forEach(message => {
    					let index = this.messages.indexOf(message);
    					if (index > -1) {
    						this.messages.splice(index, 1);
    					}
    				});
    				this.messageSelector.messages = [];
    			},
    			onFailed: (error) => {
    				console.log('error:', error);
    			}
    		});
    	},
    	recallMessage() {
    		this.actionPopup.visible = false;
    		this.goEasy.im.recallMessage({
    			messages: this.messageSelector.messages,
    			onSuccess: ()=>{
    				console.log('撤回成功');
    			},
    			onFailed: (error) => {
    				console.log('撤回失败,error:', error);
    			}
    		});
    	},
    	editRecalledMessage (content) {
    		if (this.audio.visible) {
    			this.audio.visible = false;
    		}
    		this.content = content;
    	},
    	showCheckBox () {
    		this.messageSelector.messages = [];
    		this.messageSelector.visible = true;
    		this.actionPopup.visible = false;
    	},
    	selectMessages (e) {
    		const selectedMessageIds = e.detail.value;
    		let selectedMessages = [];
    		this.messages.forEach(message => {
    			if(selectedMessageIds.includes(message.messageId)){
    				selectedMessages.push(message);
    			}
    		})
    		this.messageSelector.messages = selectedMessages;
    	},
    	loadHistoryMessage(scrollToBottom) {//历史消息
    		let lastMessageTimeStamp = null;
    		let lastMessage = this.messages[0];
    		if (lastMessage) {
    			lastMessageTimeStamp = lastMessage.timestamp;
    		}
    		this.goEasy.im.history({
    			userId: this.friend.uuid,
    			lastTimestamp: lastMessageTimeStamp,
    			limit: 10,
    			onSuccess: (result) => {
    				console.log("result:", result);
    				uni.stopPullDownRefresh();
    				let messages = result.content;
    				if (messages.length === 0) {
    					this.allHistoryLoaded = true;
    				} else {
    					this.messages = messages.concat(this.messages);
    					if (scrollToBottom) {
    						this.scrollToBottom();
    						//收到的消息设置为已读
    						this.markPrivateMessageAsRead();
    					}
    				}
    			},
    			onFailed: (error) => {
    				//获取失败
    				console.log('获取历史消息失败:',error);
    				uni.stopPullDownRefresh();
    			}
    		});
    	},
    	//语音录制按钮和键盘输入的切换
    	switchAudioKeyboard() {
    		this.audio.visible = !this.audio.visible;
    		if(uni.authorize){
    			uni.authorize({
    				scope : 'scope.record',
    				fail: () => {
    					uni.showModal({
    						title: '获取录音权限失败',
    						content : '请先授权才能发送语音消息！'
    					});
    				}
    			});
    		}
    	},
    	onRecordStart () {
    		try{
    			recorderManager.start();
    		}catch(e){
    			uni.showModal({
    				title: '录音错误',
    				content : '请在app和小程序端体验录音，Uni官方明确H5不支持getRecorderManager, 详情查看Uni官方文档'
    			});
    		}
    	},
    	onRecordEnd () {
    		try{
    			recorderManager.stop();
    		}catch(e){
    			console.log(e);
    		}
    	},
    	createVideoMessage () {
    		uni.chooseVideo({
    			success : (res) => {
    				let videoMessage = this.goEasy.im.createVideoMessage({
    					to : {
    						id : this.friend.uuid,
    						type : this.GoEasy.IM_SCENE.PRIVATE,
    						data : {
    							name:this.friend.name,
    							avatar:this.friend.avatar
    						}
    					},
    					file: res,
    					onProgress :function (progress) {
    						console.log(progress)
    					},
    					notification : {
    						title : this.currentUser.name + '发来一个视频',
    						body : '[视频消息]'		// 字段最长 50 字符
    					}
    				});
    				this.sendMessage(videoMessage);
    			}
    		})
    	},
    	createImageMessage() {
    		uni.chooseImage({
                count : 9,
    			success: (res) => {
    				res.tempFiles.forEach(file => {
    					let imageMessage = this.goEasy.im.createImageMessage({
    						to : {
    							id : this.friend.uuid,
    							type : this.GoEasy.IM_SCENE.PRIVATE,
    							data : {
    								name:this.friend.name,
    								avatar:this.friend.avatar
    							}
    						},
    						file: file,
    						onProgress :function (progress) {
    							console.log(progress)
    						},
    						notification : {
    							title : this.currentUser.name + '发来一张图片',
    							body : '[图片消息]'		// 字段最长 50 字符
    						}
    					});
    					this.sendMessage(imageMessage);
    				})
    			}
    		});
    	},
    	showImageFullScreen (e) {
    		let imagesUrl = [e.currentTarget.dataset.url];
    		uni.previewImage({
    			urls: imagesUrl
    		});
    	},
    	playVideo (e) {
    		this.videoPlayer.visible = true;
    		this.videoPlayer.url = e.currentTarget.dataset.url;
    		this.$nextTick(() => {
    			this.videoPlayer.context.requestFullScreen({
    				direction : 0
    			});
    			this.videoPlayer.context.play();
    		});
    	},
    	onVideoFullScreenChange (e) {
    		//当退出全屏播放时，隐藏播放器
    		if(this.videoPlayer.visible && !e.detail.fullScreen){
    		    this.videoPlayer.visible = false;
    		    this.videoPlayer.context.stop();
    		}
    	},
    	messageInputFocusin () {
    		this.otherTypesMessagePanelVisible = false;
    		this.emoji.visible = false;
    	},
    	showEmoji () {
    		this.emoji.visible = !this.emoji.visible;
    		this.otherTypesMessagePanelVisible = false;
    	},
    	showOtherTypesMessagePanel () {
    		this.otherTypesMessagePanelVisible = !this.otherTypesMessagePanelVisible;
    		this.emoji.visible = false;
    	},
    	chooseEmoji (emojiKey) {
    		this.content +=emojiKey;
    	},
    	createCustomMessage (data) {
    		let customMessage = this.goEasy.im.createCustomMessage({
    			type : 'order',
    			payload : {
    				number : data.number,
    				goods : data.goods,
    				price : data.price
    			},
    			to : {
    				id : this.friend.uuid,
    				type : this.GoEasy.IM_SCENE.PRIVATE,
    				data : {
    					name : this.friend.name,
    					avatar: this.friend.avatar
    				}
    			},
    			notification : {
    				title : this.currentUser.name + '发来一份订单',
    				body : '[订单消息]'     // 字段最长 50 字符
    			}
    		});
    		this.sendMessage(customMessage);
    		this.customMessageFormVisible = false;
    	},
    	showCustomMessageForm () {
    		this.customMessageFormVisible = true;
    	},
    	closeCustomMessageForm () {
    		this.customMessageFormVisible = false;
    	},
    	scrollToBottom () {
    		setTimeout(() => {
    			uni.pageScrollTo({
    				scrollTop: 2000000,
    				duration: 0
    			})
    		},500);
    	},
    	markPrivateMessageAsRead () {
    		this.goEasy.im.markPrivateMessageAsRead({
    			userId: this.friend.uuid,
    			onSuccess: function () {
    				console.log('标记私聊已读成功');
    			},
    			onFailed: function (error) {
    				console.log("标记私聊已读失败",error);
    			}
    		});
    	}
    },
    // 职责:不要set的data 统一用computed实现(能用computed实现的尽量用他实现 不要用data和method处理) 命名规范：前缀加calc 有返回值的不需要传参的method用computed实现 
    computed: {
        // 查询条件变化用于监控 命名方式以 calc加data的接口in
        //calcGetStudentListIn() {
        //    return this.$_.cloneDeep(this.getStudentListIn);
        //},

        // 接口返回值处理 calc加data的接口out 命名规范：前缀加calc
        //calcGetStudentListOut() {
        //    let dataList = this.$_.cloneDeep(this.getStudentListOut.dataList);
        //    dataList.forEach((item, index) => {
        //        // 有初始化选中的Id 那么选中
        //        if (this.selctId == item.id) {
        //            this.$set(item, 'selected', true);
        //        } else {
        //            // 设置属性需要通过这种方式设置 如之前没有绑定这个属性 需要这种方式设置 不然没办法双向绑定  其他设置为false
        //            this.$set(item, 'selected', false);
        //        }
        //    });
        //    // 尽量用lodash链式语法进行数据处理
        //    const page = 1; // 第几页
        //    const limit = 5; // 每页多少条
        //    const dealList = this.$_(dataList).chain()
        //        .drop((page - 1) * limit) // 跳过前面数据
        //        .take(limit) // 取几个
        //        .filter(x => x.age <= 10) // 过滤
        //        .map(x => ({
        //            stuName: x.stuName,
        //            age: x.age
        //        })) // 映射数据
        //        .orderBy(['stuName', 'age'], ['desc', 'asc']) // 排序
        //        .uniqBy('stuName') // 去重
        //        .value();
        //    return dealList;
        //},
    },
    // 职责:格式化数据 有返回值的需要传参的method 用filters实现
    filters: {
        // 多个参数filter 调用  {{day|weekDayFmt(getStudentListIn.month)}} filter  命名规范：filter后缀加上Fmt
        //weekDayFmt(day, yearMonth) {
        //    var weekDay = moment(yearMonth + "-" + day).day();
        //    var weekObj = { 1: "一", 2: "二", 3: "三", 4: "四", 5: "五", 6: "六", 0: "日" };
        //    return weekObj[weekDay];
        //},
    },
    // 职责:数据变化后需要和接口交互
    watch: {
        // 监控查询条件的变化 自动请求数据
        //'calcGetStudentListIn': {
        //    handler(val, oldval) {
        //        if (this.$util.isChgForWatch(val, oldval, ['pageIndex', 'sarchValue'])) { // 监控对象中那些数据发生了变化
        //            this.getPageList();
        //        }
        //    },
        //    deep: true,
        //    immediate: true,
        //}
    }
};
